package com.plat.net.tcp;


import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;

/**
 * 抽象通道
 * 获取代理通道
 */
public abstract class AbstractChannel<C extends Channel> extends ChannelInitializer {

    private Channel channel;

    @Override
    protected void initChannel(Channel ch) throws Exception {
        this.channel = ch;
        pipeline(ch);
    }

    protected Channel getProxyChannel(String address, int port) throws InterruptedException {
        Bootstrap bootstrap = getBootstrap(this.channel);
        ChannelFuture future = bootstrap.connect(address, port);
        Channel channel = future.channel();
        future.addListener((ChannelFutureListener) f -> {
            if (f.isSuccess()) {
                this.channel.read();
            } else {
                this.channel.close();
            }
        });
        return channel;
    }

    protected abstract void pipeline(Channel ch) throws Exception;

    /**
     * 获取一个代理Bootstrap
     */
    protected Bootstrap getBootstrap(Channel ch) throws InterruptedException {
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(ch.eventLoop())
                .channel(ch.getClass())
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) {
                        //客户端端channel，客户端返回的数据给服务端，所以构造函数参数要传入服务端的channel
                        socketChannel.pipeline().addLast("clientHandler", new DataSwapHandler(ch));
                    }
                });

        return bootstrap;
    }
}
